Skip to content

fix(cli): keep pending-queue previews on one terminal row - #3841

Open
Sma1lboy wants to merge 1 commit into
apache:mainfrom
Sma1lboy:fix/pending-queue-single-row
Open

fix(cli): keep pending-queue previews on one terminal row#3841
Sma1lboy wants to merge 1 commit into
apache:mainfrom
Sma1lboy:fix/pending-queue-single-row

Conversation

@Sma1lboy

Copy link
Copy Markdown

Summary

limitText appends its truncation suffix behind a newline, so firstLinePreview returned a two-row string for any queued message whose first line exceeds 200 characters — despite its own contract saying "trimmed for a one-line preview".

Every element a layout component returns must occupy exactly one terminal row. pi-tui writes them between explicit CRLF separators and counts one row each, so the embedded newline shifts every later row down while the diff accounting still believes one row was written.

fitLine cannot defend against this: pi-tui's visibleWidth treats the newline as zero-width, so the composed line measures 232 columns and reads as fitting inside a 240-column terminal.

The fix collapses the preview exactly the way the sibling call site at pi-transcript-tools.ts:98 already collapses the same limitText output. limitText itself is unchanged — its multiline suffix is correct for the block contexts that use it.

Fixes #3824

Verification

npm run lint, npm run format:check, npm --workspace maka-agent run typecheck, and node --test packages/cli/dist/__tests__/pi-transcript.test.js (78/78) all pass. The new test was confirmed RED before the fix by reverting firstLinePreview and rebuilding.

Captured live in a 240×20 tmux pane, driving the real MakaPiLayoutComponent and MakaPendingQueueComponent through the real pi-tui TuiMainScreen against a real terminal. Only the editor is stubbed, at a fixed one-row height, so it cannot itself be the source of drift.

Before — the queued message occupies rows 16 and 17:

16:Steering: STEER-START xxxxxxxxxxxxxxxxxxxxxxxx…   (210 columns)
17:... 42 chars truncated
18:⌥+↑ 取回队列以重新编辑
19:EDITOR-ROW
20:Maka · Auto · repro-model · repro · /repro

After — one element, one row:

17:Steering: STEER-START xxxxx… ... 42 chars truncated
18:⌥+↑ 取回队列以重新编辑
19:EDITOR-ROW
20:Maka · Auto · repro-model · repro · /repro

Row accounting across a width scan, before → after:

Width Elements Physical rows (before) Physical rows (after)
100 2 2 2
210 2 2 2
211 2 3 2
232 2 3 2
240 2 3 2
300 2 3 2

The newline survives at widths 211–320 and at no width below 211 — below that, fitLine truncates before the newline lands, which is why narrow terminals never showed this. That matches the "roughly ≥210 columns" note in the issue.

Review focus

The issue states the misalignment persists frame to frame until the queue drains. I have the row-count mismatch on screen and the code path (pi-tui-layout.ts:174 sizes the viewport from pendingLines.length), but I did not reproduce accumulating drift across incremental renders — pi-tui full-redraws each frame in my harness, which self-heals. The fix addresses the contract violation that causes it; I am flagging the gap rather than claiming more than I observed.

The issue also suggests defense-in-depth by stripping \r?\n in the layout component. I left that out: it would mask future contract violations at the boundary rather than at the call site that creates them, and every other producer already collapses correctly. Happy to add it if a maintainer prefers the belt-and-braces.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Opus 5 (Claude Code) — investigation, the fix, the regression test, and the tmux reproduction harness. Reviewed and verified locally by me; the affected commit carries a Generated-by trailer.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@M4n5ter
M4n5ter force-pushed the fix/pending-queue-single-row branch from 51162dd to f1ea9d4 Compare August 26, 2026 08:53
`limitText` appends its truncation suffix behind a newline, so
`firstLinePreview` returned a two-row string for any queued message whose
first line exceeds 200 characters. Every element a layout component returns
must occupy exactly one terminal row: pi-tui writes them between explicit
CRLF separators and counts one row each, so the embedded newline shifted
every later row down while the diff accounting still believed one row was
written.

`fitLine` cannot catch this — pi-tui's `visibleWidth` treats the newline as
zero-width, so a 232-column line reads as fitting inside a 240-column
terminal and is passed through untouched.

Collapse the preview the way the sibling call site in
`pi-transcript-tools.ts` already collapses the same `limitText` output.

Generated-by: Claude Opus 5
@M4n5ter
M4n5ter force-pushed the fix/pending-queue-single-row branch from f1ea9d4 to b2c2836 Compare August 26, 2026 09:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(cli): pending-queue preview embeds a literal newline into a single-row slot

1 participant